package com.shjy.driver.util;


import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import android.app.Activity;
import android.app.ActivityManager;
import android.app.AlertDialog;
import android.app.PendingIntent;
import android.app.PendingIntent.CanceledException;
import android.app.ProgressDialog;
import android.app.ActivityManager.RunningAppProcessInfo;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory.Options;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.location.Location;
import android.location.LocationManager;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.net.wifi.WifiManager;
import android.os.Environment;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.webkit.WebView;
import android.widget.ArrayAdapter;
import android.widget.MultiAutoCompleteTextView;
import android.widget.MultiAutoCompleteTextView.Tokenizer;
import android.widget.Toast;

public class AppUtil {
	
	private static final String TAG = "AppUtil"; 
	public static final long HALF_MINUTE = 30000;
	public static final long HALF_HOUR = 1800000;
	public static final long ONE_HOUR = 3600000;
	public static final long FIVE_MINUTES = 300000;
	public static final long TEN_MINUTES = 600000;
	public static final long ONE_MINUTE = 60000;
	public static final long TWO_MINUTES = 120000;
	public static final long FOUR_MINUTES = 240000;
	//public static final long TEN_SECONDS = 240000;
	public static final int POSITION_TIMEOUT = 120000;
	public static final int ONE_KM = 1000;
	
	public static final String ISO_LANG_CHINESE = "CHI";
	
	private final static double PI   = 3.14159265354;  
    private final static double D2R     = 0.017453 ;  
    private final static double a2  = 6378137.0;  
    private final static double e2  = 0.006739496742337; 
	
    public final static double threshold = 50;

    
	public static void setAutoCompleteTextViewAdapter(Context context, MultiAutoCompleteTextView view, String[] strings){
		ArrayAdapter<String> adapter = new ArrayAdapter<String>(context,
				android.R.layout.simple_dropdown_item_1line, strings);
		view.setAdapter(adapter);
		view.setTokenizer(new Tokenizer() {
			@Override
			public CharSequence terminateToken(CharSequence text) {
				return text + " ";
			}

			@Override
			public int findTokenStart(CharSequence text, int cursor) {
				return 0;
			}

			@Override
			public int findTokenEnd(CharSequence text, int cursor) {
				return text.length();
			}
		});
	}	
	

	static int currentTexRef = 0x0100;

	public static int getNextTexRef() {
		if (currentTexRef >= 0x8FFF)
			currentTexRef = 0x0100;
		return currentTexRef++;
	}
	
	/**
	 * 
	 * @param url
	 * @return
	 */
	public static Bitmap getHttpBitmap(String url) {
		URL myFileUrl = null;
		Bitmap bitmap = null;
		try {
			myFileUrl = new URL(url);
		} catch (MalformedURLException e) {
			e.printStackTrace();
		}
		try {
			HttpURLConnection conn = (HttpURLConnection) myFileUrl
					.openConnection();
			conn.setConnectTimeout(0);
			conn.setDoInput(true);
			conn.connect();
			InputStream is = conn.getInputStream();
			bitmap = BitmapFactory.decodeStream(is);
			is.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return bitmap;
	}

	public static String TrimContent(String input){
		if(input==null) return "";
		StringBuilder sb = new StringBuilder();
		for(int i=0;i<input.length();i++){
			if(input.charAt(i)==' '){
				continue;
			}else{
				sb.append(input.charAt(i));
			}
		}
		return sb.toString();
	}
	
	public static Long getUTCTime() {
		Calendar cal=Calendar.getInstance();
		cal.setTimeZone(TimeZone.getTimeZone("gmt"));
		return cal.getTimeInMillis();
	}
	
	public static Long getLocalTime() {
		Calendar cal=Calendar.getInstance();
		return cal.getTimeInMillis();
	}
	
	public static byte[] postViaHttpConnection(byte[] requestToSend, String urlStr){
		int status = 0;
		HttpURLConnection c = null;
		InputStream is = null;
		OutputStream os = null;
		try {
			if(requestToSend != null){
				//Log.d("HttpConnection","postViaHttpConnection request:\n"+new String(requestToSend,"UTF-8"));
			}else{
				//Log.d("HttpConnection","postViaHttpConnection urlStr:\n"+urlStr);
			}
			URL url = new URL(urlStr);

			c = (HttpURLConnection) url.openConnection();
			c.setConnectTimeout(POSITION_TIMEOUT);
			c.setReadTimeout(POSITION_TIMEOUT);
			if(requestToSend != null){
				c.setDoInput(true);
				c.setUseCaches(false);
				c.setDoOutput(true);
				c.setRequestMethod("GET");
				// Getting the output stream may flush the headers
				os = c.getOutputStream();
				os.write(requestToSend);
				os.flush(); // Optional, openInputStream will flush
			}
			// Get the status code, causing the connection to be made
			status = c.getResponseCode();
			if ((status == HttpURLConnection.HTTP_NOT_IMPLEMENTED)
					|| (status == HttpURLConnection.HTTP_VERSION)
					|| (status == HttpURLConnection.HTTP_INTERNAL_ERROR)
					|| (status == HttpURLConnection.HTTP_GATEWAY_TIMEOUT)
					|| (status == HttpURLConnection.HTTP_BAD_GATEWAY)) {
				if (is != null) {
					is.close();
				}
				if (os != null) {
					os.close();
				}
				if (c != null) {
					c.disconnect();
				}
				return null;
			}
			// Only HTTP_OK (200) means the content is returned.
			if (status != HttpURLConnection.HTTP_OK) {
				throw new Exception("Response status not OK [" + status + "]");
			}

			is = c.getInputStream();
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			byte[] buffer = new byte[1024];
			int realRead;
			while ((realRead = is.read(buffer)) != -1) {
				baos.write(buffer, 0, realRead);
			}
			byte[] ret = baos.toByteArray();
			baos.close();
			is.close();
			Log.d("HttpConnection","postViaHttpConnection resp length:"+ret.length);
			//Log.i("WebServices","postViaHttpConnection resp:"+new String(ret));
			return ret;

		}catch (Exception e) {
			Log.e("HttpConnection",e.getMessage());
			return null;
		} catch(OutOfMemoryError e){
			Log.e("HttpConnection",e.getMessage());
			return null;
		}finally{
			try {
				if (os != null) {
					os.close();
				}
				if (c != null) {
					c.disconnect();
				}
			} catch (Exception e) {
			}
		}
	
	}
	
	public static boolean isWiFiActive(Context inContext) { 
		WifiManager wm=null;
		try{
			wm = (WifiManager) inContext.getSystemService(Context.WIFI_SERVICE);
		}catch(Exception e){
			e.printStackTrace();
		}
		
		if(wm==null || wm.isWifiEnabled()==false) return false;
		
		return true;
		/*Context context = inContext.getApplicationContext();  
        ConnectivityManager connectivity = (ConnectivityManager) context  
                .getSystemService(Context.CONNECTIVITY_SERVICE);  
        if (connectivity != null) {  
            NetworkInfo[] info = connectivity.getAllNetworkInfo();  
            if (info != null) {  
                for (int i = 0; i < info.length; i++) {  
                    if (info[i].getTypeName().equals("WIFI") && info[i].isConnected()) {  
                        return true;  
                    }  
                }  
            }  
        }  
        return false;  */
    }
	
	public static String getLanguageProperty(String searchTerm){
		for(int i=0;i<searchTerm.length();i++){
			char c = searchTerm.charAt(i);
			int acs = (int)c;
			if(acs == 32 || (acs > 65 && acs<91) || (acs > 96 && acs<123) ){
				continue;				
			}else{
				return "CHI";
			}
		}
		return "PYN";
	} 
	
	public static String getDownloadPath() {
					
			String filePath1 = Environment.getExternalStorageDirectory()+"/";
			File file1 = new File(filePath1 + "download/");
			File file2 = new File(filePath1 + "ms.file");
			try{
				if(!file1.exists()){
					file1.mkdir();
				}
				file2.createNewFile();
				if(file2.exists()){
					file2.delete();
					return file1.getPath()+"/";
				}
			}catch(IOException e){}
			
			String filePath4 = "/sdcard/";
			File file3 = new File(filePath4 + "download/");
			File file4 = new File(filePath4 + "ms.file");
			try{
				if(!file3.exists()){
					file3.mkdir();
				}
				file4.createNewFile();
				if(file4.exists()){
					file4.delete();
					return file3.getPath()+"/";
				}
			}catch(IOException e){}
			
			String filePath6 = "/flash/";
			File file5 = new File(filePath6 + "download/");
			File file6 = new File(filePath6 + "ms.file");
			try{
				if(!file5.exists()){
					file5.mkdir();
				}
				file6.createNewFile();
				if(file6.exists()){
					file6.delete();
					return file5.getPath()+"/";
				}
			}catch(IOException e){}
		
		return null;
		//Environment.getExternalStorageState().equals(
		//		android.os.Environment.MEDIA_UNMOUNTED); // determine whether sd card is exist
	}
	
	public static String getSDPath() {
		File sdDir = Environment.getExternalStorageDirectory();// get the root directory
		return sdDir.toString();
	}
	
	public static String getFileName(String url) {
		String file = url.substring(url.lastIndexOf("/")+1,url.length());
		if(file.endsWith("apk")){
			return file;
		}else{
			return "download.apk";
		}
	}

	//only for china
	public static String getBuildingNumber(String address){
		int start = -1;
		int end = -1;
		char[] ch = address.toCharArray();
	    for (int i = 0; i < ch.length; i++) {
	    	char c = ch[i];
	    	if(c>47 && c<58){	    		
	    		if(start == -1){
	    			start = i;
	    		}
	    	}else{
	    		if(start > -1){
	    			end = i;
	    			return address.substring(start,end);
	    		}
	    	}
	    }
	    if(start > -1 && end ==-1){
			return address.substring(start);
		}
	    return address;
	}
		public static boolean isFileExists(Context context,String fileName) {
		InputStream is = null;
		try {
			is = context.getAssets().open(fileName);
			if(is!=null && is.available()>0){
				is.close();
				return true;
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return false;
		
	}
	
	
	public static Bitmap drawTextAtBitmap(Bitmap bitmap,int number){  
        int x = bitmap.getWidth();  
        int y = bitmap.getHeight();  
        Bitmap newbit = Bitmap.createBitmap(x, y, Bitmap.Config.ARGB_8888);  
        Canvas canvas = new Canvas(newbit);  
        Paint paint = new Paint();
        canvas.drawBitmap(bitmap, 0, 0, paint);  
        paint.setColor(Color.WHITE);        
        paint.setTextSize(20);
        if (number<10) {
        	canvas.drawText(String.valueOf(number), 12 , 30, paint);
        } else {
        	canvas.drawText(String.valueOf(number), 8 , 30, paint);
        }  
        canvas.save(Canvas.ALL_SAVE_FLAG);  
        canvas.restore();  

        return newbit;  
   }

	/**
	 * 获取手机型号
	 *
	 * @return  手机型号
	 */
	public static String getSystemModel() {
		return android.os.Build.MODEL;
	}

	/**
	 * 获取手机厂商
	 *
	 * @return  手机厂商
	 */
	public static String getDeviceBrand() {
		return android.os.Build.BRAND;
	}

	/**
     * 根据两个位置的经纬度，来计算两地的距离（单位为KM）
     * 参数为String类型
     * @param lat1 用户纬度
     * @param lng1 用户经度
     * @param lat2 商家纬度
     * @param lng2 商家经度
     * @return
     */
    public static double getDistance(String lat1Str, String lng1Str, String lat2Str, String lng2Str) {
        Double lat1 = Double.parseDouble(lat1Str);
        Double lng1 = Double.parseDouble(lng1Str);
        Double lat2 = Double.parseDouble(lat2Str);
        Double lng2 = Double.parseDouble(lng2Str);

        double radLat1 = rad(lat1);//纬度转换度数
        double radLat2 = rad(lat2);//纬度转换度数
        double difference = radLat1 - radLat2;
        double mdifference = rad(lng1) - rad(lng2);
        double distance = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(difference / 2), 2)
                + Math.cos(radLat1) * Math.cos(radLat2)
                * Math.pow(Math.sin(mdifference / 2), 2)));
        distance = distance * 6378.137;
        distance = Math.round(distance * 10000) / 10000.0;


        return distance;
    }

    private static double rad(double d) {
        return d * Math.PI / 180.0;
    }

	/**
	 * 判断GPS是否可用
	 */
	public static boolean isGPSAvailable(Context context) {
		LocationManager locationManager = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
		boolean gps = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
		boolean net = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
		if(gps || net){
			return true;
		}
		return false;
	}

	public static Bitmap zoomBitmap(Bitmap bitmap, int width, int height) {
        int w = bitmap.getWidth();
        int h = bitmap.getHeight();
        Matrix matrix = new Matrix();
        matrix.postScale((float) width / w, (float) height / h);
        return Bitmap.createBitmap(bitmap, 0, 0, w, h, matrix, true);
    }
	
	public static boolean isAppOnForeground(ActivityManager activityManager,String packageName) { 
        // Returns a list of application processes that are running on the device 
        List<RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses(); 
        if (appProcesses == null) return false; 
        for (RunningAppProcessInfo appProcess : appProcesses) { 
            // importance: 
            // The relative importance level that the system places  
            // on this process. 
            // May be one of IMPORTANCE_FOREGROUND, IMPORTANCE_VISIBLE,  
            // IMPORTANCE_SERVICE, IMPORTANCE_BACKGROUND, or IMPORTANCE_EMPTY. 
            // These constants are numbered so that "more important" values are 
            // always smaller than "less important" values. 
            // processName: 
            // The name of the process that this object is associated with. 
            if (appProcess.processName.equals(packageName) 
                    && appProcess.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND) { 
                return true; 
            } 
        } 
        return false; 
}
	
	public static boolean isAppRunning(Context context,String packageName) { 
		if(packageName == null) return false;
        // Returns a list of application processes that are running on the device 
		ActivityManager activityManager = (ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE);
        List<RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses(); 
        if (appProcesses == null) return false; 
        for (RunningAppProcessInfo appProcess : appProcesses) { 
            // importance: 
            // The relative importance level that the system places  
            // on this process. 
            // May be one of IMPORTANCE_FOREGROUND, IMPORTANCE_VISIBLE,  
            // IMPORTANCE_SERVICE, IMPORTANCE_BACKGROUND, or IMPORTANCE_EMPTY. 
            // These constants are numbered so that "more important" values are 
            // always smaller than "less important" values. 
            // processName: 
            // The name of the process that this object is associated with. 
            if (appProcess.processName.equals(packageName)) { 
                return true; 
            } 
        } 
        return false; 
	}
	
	public static boolean checkNetworkStatus(Context context){
		boolean resp = false;
		final ConnectivityManager connMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
		final NetworkInfo wifi = connMgr.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
		NetworkInfo activeNetInfo = connMgr.getActiveNetworkInfo();   
		if (activeNetInfo != null) {
			resp = true;
		}
		return resp;
	}
	
	public static void installAPK(String fileName, Context context) {
		Intent intent = new Intent(Intent.ACTION_VIEW);
		intent.setDataAndType(Uri.fromFile(new File(fileName)), "application/vnd.android.package-archive");
		context.startActivity(intent);
	}	
	
	public static void enableWifi(Context context){
		try{
			WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
			if (!wifiManager.isWifiEnabled()) {   
				wifiManager.setWifiEnabled(true);  
			}
		}catch(Exception e){
			e.printStackTrace();
		}
	}
	
	public static void enableGPS(Context context){
		LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
		if(!locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)){
		
	        Intent GPSIntent = new Intent();
	        GPSIntent.setClassName("com.android.settings",
	                "com.android.settings.widget.SettingsAppWidgetProvider");
	        GPSIntent.addCategory("android.intent.category.ALTERNATIVE");
	        GPSIntent.setData(Uri.parse("custom:3"));
	        try {
	            PendingIntent.getBroadcast(context, 0, GPSIntent, 0).send();
	        } catch (CanceledException e) {
	            e.printStackTrace();
	        }    
		}
	}
	
	public static Object invokeMethod(String methodName, Object[]  arg, Context context) throws Exception {

		ConnectivityManager cm = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
	     
        Class ownerClass = cm.getClass();

        Class[]  argsClass = null;
        if (arg != null) {
            argsClass = new Class[1];
            argsClass[0] = arg.getClass();
        }

        Method method = ownerClass.getMethod(methodName, argsClass);

        return method.invoke(cm, arg);
    }
	
	public static Object invokeBooleanArgMethod(String methodName, boolean value, Context context) throws Exception {

   	 ConnectivityManager cm = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
	     
        Class ownerClass = cm.getClass();

        Class[] argsClass = new Class[1];
        argsClass[0] = boolean.class;

        Method method = ownerClass.getMethod(methodName,argsClass);

        return method.invoke(cm, value);
   }
	
    public static boolean canToggleGPS(Context context) {
   	    PackageManager pacman = context.getPackageManager();
   	    PackageInfo pacInfo = null;

   	    try {
   	        pacInfo = pacman.getPackageInfo("com.android.settings", PackageManager.GET_RECEIVERS);
   	    } catch (NameNotFoundException e) {
   	        return false; //package not found
   	    }

   	    if(pacInfo != null){
   	        for(ActivityInfo actInfo : pacInfo.receivers){
   	            //test if recevier is exported. if so, we can toggle GPS.
   	            if(actInfo.name.equals("com.android.settings.widget.SettingsAppWidgetProvider") && actInfo.exported){
   	                return true;
   	            }
   	        }
   	    }

   	    return false; //default
   }
	
	public static void enableWireless(boolean enbale,Context context){
		Log.d(TAG, "toggling wireless, set wireless to " + enbale);
		
		try{
			invokeBooleanArgMethod("setMobileDataEnabled",enbale,context);
			//invokeBooleanArgMethod("setDataRoaming",enbale,context);
		}catch(Exception e){
			e.printStackTrace();
		}
	}
	
	public static boolean isWirelessEnabled(Context context){
		try {
			return Boolean.parseBoolean(invokeMethod("getMobileDataEnabled",null,context).toString());
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return true;
		
	}
	
	public static boolean isNumeric(String str){ 
		Pattern pattern = Pattern.compile("[0-9]*"); 
		return pattern.matcher(str).matches(); 
	}
	
	public static String getIMEI(Context context){
		
		TelephonyManager tm = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
        
		String imei = tm.getSubscriberId();
		
		if(imei == null) imei = "";
		//imei = "123223233223122";
		//imei = "460036161325091";
		imei = "460036161325091";
		return imei;
	}


	public static void writeData(String text) {
		String filePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Android/data/com.shjy.driver/files/Download/";
		String fileName = "";
		try {
			fileName = "log-"+formatDate(new Date())+".txt";
		}catch (Exception ex){
			ex.printStackTrace();
		}

		writeTxtToFile(text, filePath, fileName);
	}

	private static  String formatDate(Date date) throws Exception{
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		return sdf.format(date);
	}

	// 将字符串写入到文本文件中
	public static void writeTxtToFile(String strcontent, String filePath, String fileName) {
		//生成文件夹之后，再生成文件，不然会出错
		makeFilePath(filePath, fileName);

		String strFilePath = filePath+fileName;
		// 每次写入时，都换行写
		String strContent = strcontent + "\r\n";
		try {
			File file = new File(strFilePath);
			if (!file.exists()) {
				Log.d("TestFile", "Create the file:" + strFilePath);
				file.getParentFile().mkdirs();
				file.createNewFile();
			}
			RandomAccessFile raf = new RandomAccessFile(file, "rwd");
			raf.seek(file.length());
			raf.write(strContent.getBytes());
			raf.close();
		} catch (Exception e) {
			Log.e("TestFile", "Error on write File:" + e);
		}
	}

	// 生成文件
	public static File makeFilePath(String filePath, String fileName) {
		File file = null;
		makeRootDirectory(filePath);
		try {
			file = new File(filePath + fileName);
			if (!file.exists()) {
				file.createNewFile();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return file;
	}

	// 生成文件夹
	public static void makeRootDirectory(String filePath) {
		File file = null;
		try {
			file = new File(filePath);
			if (!file.exists()) {
				file.mkdir();
			}
		} catch (Exception e) {
			Log.i("error:", e+"");
		}
	}
   
}

